/*
 * $Id$
 *
 * Copyright (c) 2011 António Godinho, All Rights Reserved.
 * (nunes.godinho@gmail.com)
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Last changed on $Date$
 * Last changed by $Author$
 */
package pt.isec.gps.fastnote;

import java.io.IOException;
import java.io.StringReader;

import javax.swing.JTextPane;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.StyledDocument;
import javax.swing.text.StyledEditorKit;
import javax.swing.text.html.HTML;
import javax.swing.text.html.HTMLDocument;
import javax.swing.text.html.HTMLEditorKit;
import javax.swing.text.html.HTMLEditorKit.Parser;
import javax.swing.text.html.HTMLEditorKit.ParserCallback;

/**
 * 
 * Class that implements methods for work with HTML setCharacterAttributes(JTextPane editor, HTMLEditorKit editorKit,
 * AttributeSet attr, boolean replace) insertHTML(HTMLDocument doc, int offset, String html, int popDepth, int
 * pushDepth, HTML.Tag insertTag)
 * 
 * @author Antonio Godinho
 * @version $Revision$
 */
public class TextEffectsUtils {

    private static Parser defaultParser = null;

    protected static void setCharacterAttributes(JTextPane editor, HTMLEditorKit editorKit, AttributeSet attr,
            boolean replace) {
        int selectionStart = editor.getSelectionStart();
        int selectionEnd = editor.getSelectionEnd();
        if (selectionStart != selectionEnd) {
            StyledDocument document = (StyledDocument) editor.getDocument();
            document.setCharacterAttributes(selectionStart, selectionEnd - selectionStart, attr, replace);
        }
        StyledEditorKit styledEditorKit = editorKit;
        MutableAttributeSet inputAttributes = styledEditorKit.getInputAttributes();
        if (replace) {
            inputAttributes.removeAttributes(inputAttributes);
        }
        inputAttributes.addAttributes(attr);
    }

    public static void insertHTML(HTMLDocument document, int offset, String html, int popDepth, int pushDepth,
            HTML.Tag insertTag) throws BadLocationException, IOException {
        if (offset > document.getLength()) {
            throw new BadLocationException("Invalid location", offset);
        }

        Parser p = ensureParser(document);
        ParserCallback receiver = document.getReader(offset, popDepth, pushDepth, insertTag);
        Boolean ignoreCharset = (Boolean) document.getProperty("IgnoreCharsetDirective");
        p.parse(new StringReader(html), receiver, (ignoreCharset == null) ? false : ignoreCharset.booleanValue());
        receiver.flush();
    }

    private static Parser ensureParser(HTMLDocument document) throws IOException {
        javax.swing.text.html.HTMLEditorKit.Parser parser = document.getParser();
        if (parser == null) {
            parser = getParser();
        }
        if (parser == null) {
            throw new IOException("Can't load parser");
        }
        return parser;
    }

    private static Parser getParser() {
        if (defaultParser == null) {
            try {
                Class<?> className = Class.forName("javax.swing.text.html.parser.ParserDelegator");
                defaultParser = (Parser) className.newInstance();
            } catch (Throwable e) {
            }
        }
        return defaultParser;
    }
}
